feat(packaging): add BlockPackageDef for hard-macro builds#167
Merged
feat(packaging): add BlockPackageDef for hard-macro builds#167
Conversation
Adds a parameterized package type used when chipflow.toml declares
`package = "block"`. Structurally a sibling of BareDiePackageDef — pins
on four sides addressed by (Side, index) — but for hard-macro targets
rather than packaged chips.
Differences vs chip packages:
- No I/O pad ring, no JTAG, no fixed clock/reset/power slots. Blocks
take power via straps from the parent and route clocks/resets through
regular pins. allocate_pins() skips the bringup-pins step entirely.
- width/height are user-defined per project rather than pulled from a
fixed PACKAGE_DEFINITIONS entry, sourced from a new
[chipflow.silicon.block] table:
[chipflow.silicon]
process = "ihp_sg13g2"
package = "block"
[chipflow.silicon.block]
width = 50
height = 80
width/height are pin-slot counts, same units as QuadPackageDef. The
backend translates to physical microns using the process's pin pitch.
The lockfile flows through the existing bundle.zip pipeline unchanged —
package_type discriminator routes deserialization, and the `_file`-keyed
manifest contract on the receiving side already covers everything.
|
|
Match QuadPackageDef so the chipflow-backend can use a single packaging.map convention (W→S→E→N counter-clockwise) to translate pin indices to physical (side, slot) locations. The earlier (_Side, idx) tuple form would serialize as [side, idx] in the lockfile, which the backend's pad loader collapses to the side component alone — making every N-edge pin indistinguishable.
A block macro still needs real clock and reset boundary pins — the parent design drives them through ordinary block pins, so they must appear in the lockfile under `_core.bringup_pins`. The previous BlockPackageDef.allocate_pins skipped bringup allocation wholesale, leaving the macro with no clk/rst_n entries. Make BringupPins minimally constructible: core_power defaults to [], core_heartbeat to None. Base _allocate_bringup walks an empty power list and skips heartbeat when the pin is None, so targets without a chip-style debug ring drop those entries naturally. BlockPackageDef.bringup_pins now returns BringupPins(core_clock=1, core_reset=2) and the rest of the flow (model_post_init / allocate_pins) reuses the base path — no overrides, no special case in wire-up. Lockfile output for a block carries the same _core shape as a chip, just containing only clk and rst_n.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a parameterized package type used when chipflow.toml declares
package = "block". Structurally a sibling ofBareDiePackageDef— pins on four sides addressed by(Side, index)— but for hard-macro targets rather than packaged chips.Differences vs chip packages
allocate_pins()skips the chip-package bringup step (the_allocate_bringupcall that reserves clock/reset/power/JTAG slots at fixed positions).width/heightaren't fixed values inPACKAGE_DEFINITIONS— they come from a new[chipflow.silicon.block]table. The resolver inlock_pins()constructs aBlockPackageDefinstance from config whenpackage = "block".chipflow.toml shape
widthandheightare pin-slot counts, same units asQuadPackageDef.width/.height— not microns. Translation to physical dimensions happens at the backend using the process's pin pitch.What stays the same
BlockPackageDefis added to thePackageDefdiscriminated union; lockfile serialization works unchanged.What's left for the backend
Backend grows a "block mode" code path: detect
package_type == "BlockPackageDef"from the lockfile, run the ORFS macro flow (different floorplan + PnR strategy from chip flow), output LEF / Liberty / GDS / Verilog stub. None of that is in this PR.Test plan
pytest --ignore=tests/test_cli_integration.py— 69 passed, 10 skipped.ruff check chipflow/ tests/clean.tests/test_block_package.pycovers: perimeter slot count, no bringup reservation, abstract bringup property raises (so accidental calls fail loud), pydantic round-trip.Related
This PR is independent of #163 — they touch disjoint files.